/**
 * @file      md5sum.h
 * @author    希哈科技 (@csdn 希哈科技)
 * @brief     MD5 值计算函数头文件
 * @version   0.1
 * @date      2022-08-12
 *
 * @copyright Copyright (c) 2022 希哈科技 http://t.csdn.cn/uEbVw
 *
 * @note      历史记录: 
 *            - 源码来源：http://t.csdn.cn/uEbVw 依据 希哈科技 源码添加注释，依据编码规范重构
 * @warning
 * @par       修改记录: 
 * <table>
 * <tr><th>date          <th>Version    <th>Author      <th>Description    </tr>
 * <tr><td>2022-08-12    <td> 0.1       <td>wzzlyzdn       <td>创建初始版本    </tr>
 * </table>
 */

#ifndef MD5SUM_H
#define MD5SUM_H

/**
 * @struct    MD5_CTX    [md5sum.h]
 * @brief     存储 MD5 值计算中间变量
 * 
 * 
 */
typedef struct
{
    unsigned int count[2];
    unsigned int state[4];
    unsigned char buffer[64];
} MD5_CTX;

#define READ_DATA_SIZE 1024
#define MD5_SIZE 16
#define MD5_STR_LEN (MD5_SIZE * 2)

#define F(x, y, z) ((x & y) | (~x & z))
#define G(x, y, z) ((x & z) | (y & ~z))
#define H(x, y, z) (x ^ y ^ z)
#define I(x, y, z) (y ^ (x | ~z))
#define ROTATE_LEFT(x, n) ((x << n) | (x >> (32 - n)))

#define FF(a, b, c, d, x, s, ac)  \
    {                             \
        a += F(b, c, d) + x + ac; \
        a = ROTATE_LEFT(a, s);    \
        a += b;                   \
    }
#define GG(a, b, c, d, x, s, ac)  \
    {                             \
        a += G(b, c, d) + x + ac; \
        a = ROTATE_LEFT(a, s);    \
        a += b;                   \
    }
#define HH(a, b, c, d, x, s, ac)  \
    {                             \
        a += H(b, c, d) + x + ac; \
        a = ROTATE_LEFT(a, s);    \
        a += b;                   \
    }
#define II(a, b, c, d, x, s, ac)  \
    {                             \
        a += I(b, c, d) + x + ac; \
        a = ROTATE_LEFT(a, s);    \
        a += b;                   \
    }

void md5_init(MD5_CTX *context);
void md5_update(MD5_CTX *context, unsigned char *input, unsigned int inputlen);
void md5_final(MD5_CTX *context, unsigned char digest[16]);
void md5_transform(unsigned int state[4], unsigned char block[64]);
void md5_encode(unsigned char *output, unsigned int *input, unsigned int len);
void md5_decode(unsigned int *output, unsigned char *input, unsigned int len);
int md5sum(const char *file_path, char *md5_str);

#endif /* MD5SUM_H */
